package com.ikas.ai.framework.jexl.function;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Random;

/**
 * @Description: 数学函数
 * @Author: qi.yilai
 * @Date: 2023/6/14 14:25
 * @Version: 1.0.0
 **/
public class MathFunction implements JexlFunction {

    /**
     * 开平方运算
     *
     * @param a
     * @return
     */
    public double sqrt(double a) {
        return Math.sqrt(a);
    }

    /**
     * 自然常数的指数运算， e ^ a
     *
     * @param a
     * @return
     */
    public double exp(double a) {
        return Math.exp(a);
    }

    /**
     * 以10为底数，获取a的对数
     *
     * @param a
     * @return
     */
    public double log10(double a) {
        return Math.log10(a);
    }

    /**
     * 2为底数，获取a的对数
     *
     * @param a
     * @return
     */
    public double log2(double a) {
        return Math.log10(a) / Math.log10(2);
    }

    /**
     * 自然数为底数的函数
     * @param a
     * @return
     */
    public double ln(double a) {
        return Math.log(a);
    }

    /**
     * 绝对值
     *
     * @param a
     * @return
     */
    public double abs(double a) {
        return Math.abs(a);
    }

    /**
     * 正弦函数
     *
     * @param a
     * @return
     */
    public double sin(double a) {
        return Math.sin(a);
    }

    /**
     * 余弦函数
     *
     * @param a
     * @return
     */
    public double cos(double a) {
        return Math.cos(a);
    }

    /**
     * 正切函数
     *
     * @param a
     * @return
     */
    public double tan(double a) {
        return Math.tan(a);
    }

    /**
     * 四舍五入
     *
     * @param a
     * @return
     */
    public double round(double a, int b) {
        BigDecimal bd = new BigDecimal(String.valueOf(a));
        bd = bd.setScale(b, RoundingMode.HALF_UP);
        return bd.doubleValue();
    }

    /**
     * 向下取整
     *
     * @param a
     * @return
     */
    public double floor(double a) {
        return Math.floor(a);
    }

    /**
     * 指数运算
     *
     * @param a
     * @param b
     * @return
     */
    public double pow(double a, double b) {
        return Math.pow(a, b);
    }

    /**
     * 实数符号
     *
     * @param a
     * @return
     */
    public double signum(double a) {
        if (a > 0) {
            return 1;
        } else if (a == 0) {
            return 0;
        } else {
            return -1;
        }
    }

    /**
     * 生成随机的double
     *
     * @return
     */
    public double rand(long seed) {
        return new Random(seed).nextDouble();
    }

    /**
     * e^x-1
     * @param numColumn
     * @return
     */
    public double expml(long numColumn) {
        return Math.expm1(numColumn);
    }

    /**
     * 标准的正态分布的随机数
     *
     * @return
     */
    public double randn(long seed) {
        return new Random(seed).nextGaussian();
    }

    /**
     * 反余弦函数
     *
     * @return
     */
    public double acos(double a) {
        return Math.acos(a);
    }

    /**
     * 反正弦函数
     *
     * @param a
     * @return
     */
    public double asin(double a) {
        return Math.asin(a);
    }

    /**
     * 反正切函数
     *
     * @param a
     * @return
     */
    public double atan(double a) {
        return Math.atan(a);
    }

    /**
     * 立方根
     *
     * @param a
     * @return
     */
    public double cbrt(double a) {
        return Math.cbrt(a);
    }

    /**
     * 向上取整
     *
     * @param a
     * @return
     */
    public double ceil(double a){
        return Math.ceil(a);
    }

    /**
     * 双曲余弦
     *
     * @param a
     * @return
     */
    public double cosh(double a) {
        return Math.cosh(a);
    }

    /**
     * 双曲正弦函数
     *
     * @param a
     * @return
     */
    public double sinh(double a) {
        return Math.sinh(a);
    }

    /**
     * 双曲正切函数
     *
     * @param a
     * @return
     */
    public double tanh(double a) {
        return Math.tanh(a);
    }

    /**
     * e^x-1 函数
     *
     * @param a
     * @return
     */
    public double expm1(double a) {
        return Math.expm1(a);
    }

    /**
     * 平方和的平方根(斜边)函数
     *
     * @param a
     * @param b
     * @return
     */
    public double hypot(double a, double b) {
        return Math.hypot(a, b);
    }

    /**
     * 左移
     *
     * @param a
     * @param b
     * @return
     */
    public double shiftLeft(int a, int b) {
        return a << b;
    }

    /**
     * 右移
     *
     * @param a
     * @param b
     * @return
     */
    public double shiftRight(int a, int b) {
        return a >> b;
    }

    /**
     * 弧度转角度函数
     *
     * @param a
     * @return
     */
    public double toDegrees(double a) {
        return Math.toDegrees(a);
    }

    /**
     * 角度转弧度函数
     *
     * @param a
     * @return
     */
    public double toRadians(double a) {
        return Math.toRadians(a);
    }

    /**
     * 取模
     *
     * @param a
     * @param b
     * @return
     */
    public double numberMod(double a, double b) {
        return a % b;
    }

    /**
     * 均匀分布随机数函数
     *
     * @param a
     * @return
     */
    public double uniform(double a) {
        return new Random().nextDouble() * a;
    }

    /**
     * 正态分布随机数函数
     *
     * @param a
     * @return
     */
    public double normal(double a) {
        return new Random().nextGaussian() * a;
    }

    @Override
    public String namespace() {
        return "math";
    }
}
